"""
滴答清单 MCP 服务
封装滴答清单MCP服务的调用，供后端 API 和 Agent 使用
"""

import asyncio
import json
import logging
import os
from pathlib import Path
from typing import Optional, Dict, Any, List

logger = logging.getLogger(__name__)


class DidaMCPService:
    """滴答清单 MCP 服务类"""

    def __init__(self):
        """初始化滴答清单 MCP 服务"""
        # 计算 MCP 服务路径
        # 当前文件: app/backend-python/services/dida_mcp_service.py
        # 目标路径: mcp/didatodolist-mcp/main.py
        current_dir = Path(__file__).parent  # app/backend-python/services
        backend_dir = current_dir.parent  # app/backend-python
        app_dir = backend_dir.parent  # app
        project_root = app_dir.parent  # project root
        self.mcp_path = project_root / "mcp" / "didatodolist-mcp" / "main.py"

        logger.info(f"滴答清单 MCP 服务路径: {self.mcp_path}")

        if not self.mcp_path.exists():
            logger.warning(f"滴答清单 MCP 服务文件不存在: {self.mcp_path}")

        # MCP 依赖检查
        self.mcp_available = self._check_mcp_available()

    def _check_mcp_available(self) -> bool:
        """检查 MCP 是否可用"""
        # 1. 检查文件是否存在
        if not self.mcp_path.exists():
            logger.error(f"❌ 滴答清单 MCP 服务文件不存在: {self.mcp_path}")
            return False

        # 2. 检查依赖是否已安装
        try:
            from mcp import ClientSession, StdioServerParameters
            from mcp.client.stdio import stdio_client

            logger.info("✅ 滴答清单 MCP 依赖检查通过")
            return True
        except ImportError as e:
            logger.error(f"❌ 滴答清单 MCP 依赖未安装: {e}")
            return False

    async def _call_mcp_tool(
        self, tool_name: str, arguments: Dict[str, Any], env_vars: Optional[Dict[str, str]] = None
    ) -> Optional[Dict[str, Any]]:
        """
        调用滴答清单 MCP 工具

        Args:
            tool_name: 工具名称
            arguments: 工具参数
            env_vars: 环境变量（用于传递access_token等）

        Returns:
            工具返回的结果（JSON 格式），如果MCP不可用返回包含错误信息的字典
        """
        # 预检查：MCP 是否可用
        if not self.mcp_available:
            if not self.mcp_path.exists():
                logger.error(f"开发错误：滴答清单 MCP 服务文件不存在: {self.mcp_path}")
            else:
                logger.error("开发错误：滴答清单 MCP 依赖未安装（pip install fastmcp）")

            return {"success": False, "message": "请先检查滴答清单MCP服务是否启动。"}

        try:
            from mcp import ClientSession, StdioServerParameters
            from mcp.client.stdio import stdio_client

            logger.info(f"✅ 调用滴答清单 MCP 工具: {tool_name}, 参数: {arguments}")

            # 准备环境变量
            env = os.environ.copy()
            if env_vars:
                env.update(env_vars)

            # 创建 MCP 客户端
            server_params = StdioServerParameters(
                command="python",
                args=[str(self.mcp_path)],
                env=env,
            )

            async with stdio_client(server_params) as (read, write):
                async with ClientSession(read, write) as session:
                    # 初始化
                    await session.initialize()

                    # 调用工具
                    result = await session.call_tool(tool_name, arguments=arguments)

                    # 解析结果
                    result_text = (
                        result.content[0].text if hasattr(result, "content") else str(result)
                    )
                    return json.loads(result_text)

        except ImportError as e:
            logger.error(f"开发错误：滴答清单 MCP 模块未安装: {e}")
            return {"success": False, "message": "请先检查滴答清单MCP服务是否启动。"}
        except Exception as e:
            logger.error(f"滴答清单 MCP 服务调用失败: {e}", exc_info=True)
            return {"success": False, "message": f"MCP服务调用失败: {str(e)}"}

    def _call_mcp_tool_sync(
        self, tool_name: str, arguments: Dict[str, Any], env_vars: Optional[Dict[str, str]] = None
    ) -> Optional[Dict[str, Any]]:
        """
        同步方式调用滴答清单 MCP 工具

        Args:
            tool_name: 工具名称
            arguments: 工具参数
            env_vars: 环境变量

        Returns:
            工具返回的结果（JSON 格式）
        """
        try:
            # 获取或创建事件循环
            try:
                loop = asyncio.get_event_loop()
            except RuntimeError:
                loop = asyncio.new_event_loop()
                asyncio.set_event_loop(loop)

            # 运行异步函数
            return loop.run_until_complete(self._call_mcp_tool(tool_name, arguments, env_vars))
        except Exception as e:
            logger.error(f"同步调用滴答清单 MCP 工具失败: {e}")
            return None

    # ==================== 任务管理相关接口 ====================

    async def create_task(
        self, access_token: str, title: str, content: str = "", project_id: Optional[str] = None
    ) -> Optional[Dict[str, Any]]:
        """
        创建任务

        Args:
            access_token: 访问令牌
            title: 任务标题
            content: 任务内容
            project_id: 项目ID（可选）

        Returns:
            任务创建结果
        """
        arguments = {"title": title}
        if content:
            arguments["content"] = content
        if project_id:
            arguments["project_id"] = project_id

        env_vars = {"DIDA_ACCESS_TOKEN": access_token}

        return await self._call_mcp_tool("create_task", arguments, env_vars)

    async def get_tasks(
        self, access_token: str, project_id: Optional[str] = None
    ) -> Optional[Dict[str, Any]]:
        """
        获取任务列表

        Args:
            access_token: 访问令牌
            project_id: 项目ID（可选，不传则获取所有任务）

        Returns:
            任务列表
        """
        arguments = {}
        if project_id:
            arguments["project_id"] = project_id

        env_vars = {"DIDA_ACCESS_TOKEN": access_token}

        return await self._call_mcp_tool("get_tasks", arguments, env_vars)

    async def update_task(
        self, access_token: str, task_id: str, **kwargs
    ) -> Optional[Dict[str, Any]]:
        """
        更新任务

        Args:
            access_token: 访问令牌
            task_id: 任务ID
            **kwargs: 要更新的字段（title, content, status等）

        Returns:
            更新结果
        """
        arguments = {"task_id": task_id}
        arguments.update(kwargs)

        env_vars = {"DIDA_ACCESS_TOKEN": access_token}

        return await self._call_mcp_tool("update_task", arguments, env_vars)

    async def delete_task(self, access_token: str, task_id: str) -> Optional[Dict[str, Any]]:
        """
        删除任务

        Args:
            access_token: 访问令牌
            task_id: 任务ID

        Returns:
            删除结果
        """
        arguments = {"task_id": task_id}
        env_vars = {"DIDA_ACCESS_TOKEN": access_token}

        return await self._call_mcp_tool("delete_task", arguments, env_vars)

    async def complete_task(self, access_token: str, task_id: str) -> Optional[Dict[str, Any]]:
        """
        完成任务

        Args:
            access_token: 访问令牌
            task_id: 任务ID

        Returns:
            完成结果
        """
        arguments = {"task_id": task_id}
        env_vars = {"DIDA_ACCESS_TOKEN": access_token}

        return await self._call_mcp_tool("complete_task", arguments, env_vars)

    # ==================== 项目管理相关接口 ====================

    async def get_projects(self, access_token: str) -> Optional[Dict[str, Any]]:
        """
        获取项目列表

        Args:
            access_token: 访问令牌

        Returns:
            项目列表
        """
        env_vars = {"DIDA_ACCESS_TOKEN": access_token}
        return await self._call_mcp_tool("get_projects", {}, env_vars)

    async def create_project(
        self, access_token: str, name: str, color: Optional[str] = None
    ) -> Optional[Dict[str, Any]]:
        """
        创建项目

        Args:
            access_token: 访问令牌
            name: 项目名称
            color: 项目颜色（可选）

        Returns:
            项目创建结果
        """
        arguments = {"name": name}
        if color:
            arguments["color"] = color

        env_vars = {"DIDA_ACCESS_TOKEN": access_token}

        return await self._call_mcp_tool("create_project", arguments, env_vars)

    async def update_project(
        self, access_token: str, project_id: str, **kwargs
    ) -> Optional[Dict[str, Any]]:
        """
        更新项目

        Args:
            access_token: 访问令牌
            project_id: 项目ID
            **kwargs: 要更新的字段（name, color等）

        Returns:
            更新结果
        """
        arguments = {"project_id": project_id}
        arguments.update(kwargs)

        env_vars = {"DIDA_ACCESS_TOKEN": access_token}

        return await self._call_mcp_tool("update_project", arguments, env_vars)

    async def delete_project(
        self, access_token: str, project_id: str
    ) -> Optional[Dict[str, Any]]:
        """
        删除项目

        Args:
            access_token: 访问令牌
            project_id: 项目ID

        Returns:
            删除结果
        """
        arguments = {"project_id": project_id}
        env_vars = {"DIDA_ACCESS_TOKEN": access_token}

        return await self._call_mcp_tool("delete_project", arguments, env_vars)

    # ==================== 标签管理相关接口 ====================

    async def get_tags(self, access_token: str) -> Optional[Dict[str, Any]]:
        """
        获取标签列表

        Args:
            access_token: 访问令牌

        Returns:
            标签列表
        """
        env_vars = {"DIDA_ACCESS_TOKEN": access_token}
        return await self._call_mcp_tool("get_tags", {}, env_vars)

    # ==================== 统计分析相关接口 ====================

    async def get_task_statistics(
        self, access_token: str, project_id: Optional[str] = None
    ) -> Optional[Dict[str, Any]]:
        """
        获取任务统计

        Args:
            access_token: 访问令牌
            project_id: 项目ID（可选）

        Returns:
            任务统计结果
        """
        arguments = {}
        if project_id:
            arguments["project_id"] = project_id

        env_vars = {"DIDA_ACCESS_TOKEN": access_token}

        return await self._call_mcp_tool("get_task_statistics", arguments, env_vars)


# 全局实例
_dida_mcp_service = None


def get_dida_mcp_service() -> DidaMCPService:
    """获取滴答清单 MCP 服务实例（单例模式）"""
    global _dida_mcp_service
    if _dida_mcp_service is None:
        _dida_mcp_service = DidaMCPService()
    return _dida_mcp_service

